package rabid;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import common.HistoWord;

public class Centroid {
  /** 
   * Key = termName<br>
   *  Value = Average of occurrences across the files in the set
   */
  private Map points;
  private String mostFrequentTerm;
  
  private class Average {
    private int nu;
    private int de;
        
    public Average(int nu) {
      addToNumerator(nu);
    }
    
    public void addToNumerator(int nu) {
      this.nu += nu;
      de++;
    }
    
    public int evaluate() {
      return nu / de;
    }
  }
  
  public Centroid(List listOfFiles) {
    points = new HashMap();
    int highestCount = 0;
    
    Iterator files = listOfFiles.iterator();
    while(files.hasNext()) {
      IndexedFile indexedFile = (IndexedFile)files.next();
      List termCounts = indexedFile.getTermList().getTermCounts();
      
      Iterator terms = termCounts.iterator();
      while(terms.hasNext()) {
        HistoWord word = (HistoWord)terms.next();
        if(points.containsKey(word.text)) {
          Average avg = (Average)points.get(word.text);
          avg.addToNumerator(word.count.intValue());
        }
        else {
          points.put(word.text, new Average(word.count.intValue()));          
        }
        
        if(word.count.intValue() > highestCount) {
          highestCount = word.count.intValue();
          mostFrequentTerm = word.text;
        }
      }
    }    
  }
  
  /**
   * Returns a rating of how close the index file is to this centroid.
   * The smaller the number, the closer the file is.
   */
  public int computeCloseness(IndexedFile indexedFile) {
    int closeness = 0;
    
    //check all the terms in the file
    TermList termList = indexedFile.getTermList();    
    Iterator fileTerms = termList.getTermCounts().iterator();
    while(fileTerms.hasNext()) {
      HistoWord word = (HistoWord)fileTerms.next();
      int termCloseness = 0;
      if(points.containsKey(word.text)) {
        Average avg = (Average)points.get(word.text);
        termCloseness = Math.abs(avg.evaluate() - word.count.intValue());
      }
      else
        termCloseness = word.count.intValue();
      
      closeness += termCloseness;
    }
    
    //now adjust the closeness for the terms in this centroid that are not in the file
    Iterator centroidTerms = points.keySet().iterator();
    while(centroidTerms.hasNext()) {
      String term = centroidTerms.next().toString();
      if(!termList.containsKey(term)) {
        Average avg = (Average)points.get(term);
        closeness += avg.evaluate();
      }
    }
    
    return closeness; 
  }
  
  public String getMostFrequentTerm() {
    return mostFrequentTerm;
  }
}
